package us.esme.lib

/*
 * Copyright 2008 WorldWide Conferencing, LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 */


import net.liftweb._
import http._
import js._
import JE._
import JsCmds._
import SHtml._
import util._
import Helpers._
import sitemap._
import mapper._
import Loc._

import us.esme._
import model._

import scala.xml.{NodeSeq}

object ActionView {
  def loggedIn_? = User.loggedIn_?
  
  val ifIsLoggedIn = If(loggedIn_? _, "You must be logged in")

  val menuItems =
  Menu(Loc("actionMgt", List("action_view", "index"), "Action Management", 
           Snippet("action", doAction _),
           ifIsLoggedIn)) ::
  Nil

  def doAction(in: NodeSeq): NodeSeq = {
    val spanName = S.attr("span_id") openOr "NA"
    val formNodes: NodeSeq = findNode(<action:form/>, in).map(_.child) openOr NodeSeq.Empty
    val span = (findNode(<action:span/>, in).map(_.child) openOr NodeSeq.Empty)
    val table = (findNode(<action:table/>, in).map(_.child) openOr NodeSeq.Empty)
    val theName = "theName"
    val theAction = "theAction"
    val theTest = "theTest"

    var testText = ""
    var nameText = ""

    def saveIt(actionText: String): JsCmd = {

      val toSave = Action.create.name(nameText).user(User.currentUser)
      DB.use(toSave.connectionIdentifier) {
        ignore =>
        val act: Can[List[FieldError]] =
        for (a1 <- toSave.setAction(actionText);
             a2 <- a1.setTest(testText))
        yield a2.validate

        act match {
          case Full(Nil) =>
            toSave.save
            S.notice("Action added")
            redisplayActions &
            SetValById(theName, "") & SetValById(theAction, "") &
            SetValById(theTest, "")

          case Full(xs) => S.error(xs); Noop
          case Failure(msg, _, _) => S.error(msg) ; Noop
          case _ => Noop
        }
      }
    }

    def redisplayActions: JsCmd = SetHtml(spanName, displayActions)

    def displayActions: NodeSeq =
    Action.findAll(By(Action.user, User.currentUser), By(Action.removed, false),
                   OrderBy(Action.id, Ascending)) match {
      case Nil => Nil
      case xs =>
        def doLoop(toBind: NodeSeq): NodeSeq =
        xs.flatMap(at => bind("action", toBind,
                              "name" -> at.name,
                              "disabled" -> ajaxCheckbox(!at.disabled, e => {at.disabled(!e).save; Noop}),
                              "test" -> at.testText,
                              "action" -> at.actionText,
                              "remove" -> ajaxButton("Remove", () => {at.removed(true).save ; redisplayActions})))

        bind("action", table, "loop" -> doLoop _)
    }
    
    bind("action", span, "table" -> ((_: NodeSeq) => displayActions)) ++
    ajaxForm(bind("action",
                  formNodes,
                  "name" -> text("", nameText = _) % ("id" -> theName),
                  "theTest" -> textarea("", testText = _) % ("id" -> theTest),
                  "theAction" -> textarea("", saveIt) % ("id" -> theAction)))
  }
}
